﻿
namespace QdArch
{
    public class StairAction : ElementAction
    {
        private PointInputer PointInputer { get; set; }

        public StairAction() { }
        public StairAction(IDocumentEditor docEditor) : base(docEditor) 
        {
            this.commandCtrl.WriteInfo("命令：Stair");
        }
        internal static void Initilize()
        {
            ArchActions.StairAction = new StairAction();
            LcDocument.ElementActions.Add(ArchElementType.Stair, ArchActions.StairAction);
        }
        public async void ExecCreate(string[] args = null)
        {
            //1. 选择插入点
            this.PointInputer = new PointInputer(this.docEditor);
            QdStairRef stairRef = null;
            var result = await this.PointInputer.Execute("插入点:");
            if (result == null || result.ValueX == null || !(result.ValueX is Vector2)||this.PointInputer.isCancelled)
            {
                this.Cancel();
                goto End;
            }
            var stairName = "DogleggedStair";
            var stair = docRt.Document.Components.Find(ArchCategory.Stair.ToString(), stairName) as QdStair;
            if (stair == null)
            {
                stair = new QdStair(StairCategory.DogleggedStair.ToString(), stairName);
                docRt.Document.Components.Add(stair);
            }
            var instP = (Vector2)result.ValueX;
            stairRef = this.docRt.Document.CreateObject<QdStairRef>();
            stairRef.Matrix = Matrix3.GetTranslate(instP);
            stairRef.Parameters = QdStair.ParamsDefinition.New();
            stairRef.StepHeight = 150;
            stairRef.StepWidth = 260;
            stairRef.StepNum = 10;
            stairRef.LadderWidth = 1000;
            stairRef.PlatLen = 2100;
            stairRef.PlatWidth = 1200;
            stairRef.PlatThickness = 120;
            stairRef.SlabThickness = 100;
            stairRef.InsertPoint = instP;
         
            stairRef.stair = stair;
        End:
            this.PointInputer = null;
            this.EndCreating();
            this.DrawStair(stairRef);
        }
        public override void Draw(SKCanvas canvas, LcElement element, Vector2 offset)
        {
            var stairRef = element as QdStairRef;
            var curves = stairRef.ShapeCurves;
            var pen = this.GetDrawPen(element);
            if (pen == LightCAD.Runtime.Constants.defaultPen)
            {
                pen = new SKPaint { Color = SKColors.White, IsStroke = true };
            }
            DrawStairCurves(canvas, curves, stairRef.Matrix, pen);
        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        {
            var stairRef = element as QdStairRef;
            var curves = stairRef.ShapeCurves;
            var pen = this.GetDrawPen(element);
            if (pen == LightCAD.Runtime.Constants.defaultPen)
            {
                pen = new SKPaint { Color = SKColors.White, IsStroke = true };
            }
            matrix = matrix * stairRef.Matrix;
            DrawStairCurves(canvas, curves, matrix, pen);
        }
        public void DrawStairCurves(SKCanvas canvas, List<Curve2d> curves, Matrix3 matrix, SKPaint pen) 
        {
            foreach (var curve in curves)
            {
                switch (curve.Type)
                {
                    case Curve2dType.Rect2d:
                        {
                            var rect = curve as Rect2d;
                            var min = rect.Min;
                            var max = rect.Max;
                            var a = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(min)).ToSKPoint();
                            var b = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(new Vector2(max.X,min.Y))).ToSKPoint();
                            var c = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(max)).ToSKPoint();
                            var d = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(new Vector2(min.X,max.Y))).ToSKPoint();
                            canvas.DrawPoints(SKPointMode.Polygon,new SKPoint[] { a, b, c, d,a }, pen);
                            break;
                        }
                    default:
                        break;
                }
            }
        }

        private void DrawStair(QdStairRef stairRef) 
        {
            if (stairRef == null)
                return;
            stairRef.IsFireChangedEvent = true;
            this.docRt.Document.ModelSpace.InsertElement(stairRef);
            this.docRt.Action.ClearSelects();
        }
        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
        }

        #region Grip
        private QdStairRef _stairRef;
        private string _gripName;
        private Vector2 _position;

        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var stairRef = element as QdStairRef;
            var grips = new List<ControlGrip>();

            var gripInsert = new ControlGrip
            {
                Element = stairRef,
                Name = "InsertPoint",
                Position = stairRef.InsertPoint
            };
            grips.Add(gripInsert);
            return grips.ToArray();
        }

        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {
            var stairRef = element as QdStairRef;
            _stairRef = stairRef;
            if (!isEnd)
            {
                _gripName = gripName;
                _position = position;
            }
            else
            {
                if (gripName == "InsertPoint")
                {
                    var offset = position - stairRef.InsertPoint;
                    stairRef.InsertPoint = position;
                    stairRef.Matrix = Matrix3.GetTranslate(offset)*stairRef.Matrix ;
                }
            }

        }

        public override void DrawDragGrip(SKCanvas canvas)
        {
            if (_stairRef == null)
                return;
            if (_gripName == "InsertPoint")
            {
                var offset = _position - _stairRef.InsertPoint;
                var matrix = Matrix3.GetTranslate(offset) * _stairRef.Matrix;
                var curves = _stairRef.ShapeCurves;
                DrawStairCurves(canvas, curves, matrix, LightCAD.Runtime.Constants.draggingPen);
            }
         
        }
        #endregion

    }
}
